package com.xbongbong.crm.perform.query.detail;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.crm.abstracts.AbstractCrmDetailTopInfoService;
import com.xbongbong.crm.help.CustomerHelp;
import com.xbongbong.crm.help.FineClueHelp;
import com.xbongbong.crm.help.StageAverageStayTimeHelp;
import com.xbongbong.crm.service.permission.CustomerPermissionServiceImpl;
import com.xbongbong.crm.util.CrmPermissionUtil;
import com.xbongbong.i18n.util.I18nMessageUtil;
import com.xbongbong.paas.call.CallCenterService;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.domain.entity.PaasMenuEntity;
import com.xbongbong.paas.domain.entity.ext.ConditionsEntityExt;
import com.xbongbong.paas.domain.entity.ext.PaasFormDataEntityExt;
import com.xbongbong.paas.domain.entity.ext.PaasFormEntityExt;
import com.xbongbong.paas.elasticsearch.model.PaasEsModel;
import com.xbongbong.paas.elasticsearch.util.EsUtil;
import com.xbongbong.paas.enums.ConditionEnum;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.FieldTypeEnum;
import com.xbongbong.paas.enums.IndexTypeEnum;
import com.xbongbong.paas.enums.PaymentSheetTypeEnum;
import com.xbongbong.paas.enums.PlatFormEnum;
import com.xbongbong.paas.field.FieldAttrEntity;
import com.xbongbong.paas.field.LinkListPojo;
import com.xbongbong.paas.help.CloudCodeHelp;
import com.xbongbong.paas.help.CommonHelp;
import com.xbongbong.sys.help.PackageHelp;
import com.xbongbong.paas.model.PaasAppModel;
import com.xbongbong.paas.model.PaasMenuModel;
import com.xbongbong.paas.model.SearchCustomerCompanyModel;
import com.xbongbong.paas.pojo.ButtonPojo;
import com.xbongbong.paas.pojo.CustomerUserPojo;
import com.xbongbong.paas.pojo.DataDetailPojo;
import com.xbongbong.paas.pojo.DetaPhonePojo;
import com.xbongbong.paas.pojo.DetailTabPojo;
import com.xbongbong.paas.pojo.DetailTitlePojo;
import com.xbongbong.paas.pojo.FormTitlePoJo;
import com.xbongbong.paas.pojo.HandelDetailPojo;
import com.xbongbong.paas.pojo.SummaryDataPoJo;
import com.xbongbong.paas.pojo.WorkFlowPojo;
import com.xbongbong.paas.pojo.dto.FormDataListDTO;
import com.xbongbong.paas.pojo.vo.FormDataGetVO;
import com.xbongbong.paas.pojo.vo.ParseSingleRowDataVO;
import com.xbongbong.paas.service.BusinessButtonService;
import com.xbongbong.paas.service.DetailTabConfigService;
import com.xbongbong.paas.service.LinkListService;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.Arith;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.DateTimeUtil;
import com.xbongbong.paas.toolbox.util.DateUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.paas.toolbox.wrap.UserVO;
import com.xbongbong.paas.util.ExplainUtil;
import com.xbongbong.paas.util.TitleUtil;
import com.xbongbong.parent.parse.data.FormDataGetAnalysisDataHelp;
import com.xbongbong.parent.parse.data.FormDataListAnalysisDataHelp;
import com.xbongbong.pro.appdetail.pojo.MobileDetailManagerBlockPojo;
import com.xbongbong.pro.appdetail.pojo.MobileDetailMoneyItemPojo;
import com.xbongbong.pro.appdetail.pojo.MobileDetailScriptPojo;
import com.xbongbong.pro.appdetail.pojo.MobileDetailSpecialInfoPojo;
import com.xbongbong.pro.appdetail.pojo.MobileDetailStatusPojo;
import com.xbongbong.pro.constant.I18nStringConstant;
import com.xbongbong.pro.domain.entity.SearchCustomerCompanyEntity;
import com.xbongbong.pro.enums.PackageTypeEnum;
import com.xbongbong.pro.enums.SaasMarkEnum;
import com.xbongbong.pro.enums.SoukeMealEnum;
import com.xbongbong.pro.enums.fund.enums.ModelTypeEnum;
import com.xbongbong.pro.enums.permission.enums.ProPermissionAliasEnum;
import com.xbongbong.pro.form.pojo.TopPermissionsPoJo;
import com.xbongbong.pro.form.pojo.dto.FormConfigGetDTO;
import com.xbongbong.pro.formdata.pojo.dto.FormDataDetailDTO;
import com.xbongbong.pro.formdata.pojo.vo.FormDataDetailVO;
import com.xbongbong.pro.formdata.pojo.vo.MobileFormCommonDetailVO;
import com.xbongbong.pro.formexplain.pojo.dto.HandlerExplainDTO;
import com.xbongbong.pro.formexplain.pojo.vo.HandlerExplainVO;
import com.xbongbong.pro.message.model.PushModel;
import com.xbongbong.pro.permission.pojo.dto.VerifyViewPermissionDTO;
import com.xbongbong.process.operate.ProcessFieldHelp;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.ParameterConstant;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.domain.entity.CustomerFocusEntity;
import com.xbongbong.saas.domain.entity.CustomerUserEntity;
import com.xbongbong.saas.domain.entity.WorkOrderFormEntity;
import com.xbongbong.saas.enums.BusinessDetailButtonEnum;
import com.xbongbong.saas.enums.BusinessDetailTabEnum;
import com.xbongbong.saas.enums.CompanyConfigEnum;
import com.xbongbong.saas.enums.FormConfigEnum;
import com.xbongbong.saas.enums.MobileDetailBottomOperationEnum;
import com.xbongbong.saas.enums.OperateTypeEnum;
import com.xbongbong.saas.enums.SaasButtonEnum;
import com.xbongbong.saas.enums.TagEnum;
import com.xbongbong.saas.enums.WorkFlowEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.ContractEnum;
import com.xbongbong.saas.enums.business.CustomerCommunicateEnum;
import com.xbongbong.saas.enums.business.CustomerManagementEnum;
import com.xbongbong.saas.enums.business.PaymentEnum;
import com.xbongbong.saas.enums.business.PaymentSheetEnum;
import com.xbongbong.saas.enums.business.QuotationEnum;
import com.xbongbong.saas.enums.business.RefundEnum;
import com.xbongbong.saas.enums.business.SalesOpportunityEnum;
import com.xbongbong.saas.enums.dictionary.ArchivedEnum;
import com.xbongbong.saas.enums.dictionary.DictionaryEnum;
import com.xbongbong.saas.model.ContractModel;
import com.xbongbong.saas.model.CustomerCommunicateModel;
import com.xbongbong.saas.model.CustomerFocusModel;
import com.xbongbong.saas.model.CustomerUserModel;
import com.xbongbong.saas.model.FundSetModel;
import com.xbongbong.saas.model.OpportunityModel;
import com.xbongbong.saas.model.PaymentModel;
import com.xbongbong.saas.model.PaymentSheetModel;
import com.xbongbong.saas.model.QuotationModel;
import com.xbongbong.saas.model.ScoreRangeModel;
import com.xbongbong.saas.model.TagLinkModel;
import com.xbongbong.saas.model.WorkOrderFormModel;
import com.xbongbong.saas.service.toolbox.help.AttrDecimalPrecisionHelper;
import com.xbongbong.saas.service.toolbox.help.UserTeamHelp;
import com.xbongbong.saas.toolbox.help.FastJsonHelper;
import com.xbongbong.sys.domain.entity.UserEntity;
import com.xbongbong.sys.model.CompanyConfigModel;
import com.xbongbong.sys.model.FeeLogModel;
import com.xbongbong.sys.model.UserModel;
import com.xbongbong.util.NameUtil;
import org.apache.commons.collections4.CollectionUtils;
import org.elasticsearch.search.sort.SortOrder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicReference;

import static com.xbongbong.saas.toolbox.help.FastJsonHelper.getIntegerOrDefaultFromFormData;

/**
 * @author 吴峰
 * @date 2021/12/24 14:01
 */
@Service("customerDetailServiceImpl")
public class CustomerDetailTopInfoServiceImpl extends AbstractCrmDetailTopInfoService {

    private static final Logger LOGGER = LoggerFactory.getLogger(CustomerDetailTopInfoServiceImpl.class);

    @Resource
    private CompanyConfigModel companyConfigModel;
    @Resource
    private CustomerFocusModel customerFocusModel;
    @Resource
    private FineClueHelp fineClueHelp;
    @Resource
    private PaasAppModel paasAppModel;
    @Resource
    private WorkOrderFormModel workOrderFormModel;
    @Resource
    private FundSetModel fundSetModel;
    @Resource
    private PaasMenuModel paasMenuModel;
    @Resource
    private ScoreRangeModel scoreRangeModel;
    @Resource
    private CommonHelp commonHelp;
    @Resource
    private FormDataListAnalysisDataHelp formDataListAnalysisDataHelp;
    @Resource
    private FormDataGetAnalysisDataHelp formDataGetAnalysisDataHelp;
    @Resource
    private PaasEsModel paasEsModel;
    @Resource
    private CallCenterService callCenterService;
    @Resource
    private CloudCodeHelp cloudCodeHelp;
    @Resource
    private AttrDecimalPrecisionHelper attrDecimalPrecisionHelper;
    @Resource
    private PaymentModel paymentModel;
    @Resource
    private CustomerCommunicateModel customerCommunicateModel;
    @Resource
    private ContractModel contractModel;
    @Resource
    private PaymentSheetModel paymentSheetModel;
    @Resource
    private QuotationModel quotationModel;
    @Resource
    private OpportunityModel opportunityModel;
    @Resource
    private CustomerUserModel customerUserModel;
    @Resource
    private UserModel userModel;
    @Resource
    private ProcessFieldHelp processFieldHelp;
    @Resource
    private PushModel pushModel;
    @Resource
    private LinkListService linkListService;
    @Resource
    private CustomerPermissionServiceImpl customerPermissionService;
    @Resource
    private StageAverageStayTimeHelp stageAverageStayTimeHelp;
    @Resource
    private BusinessButtonService businessButtonService;
    @Resource
    private UserTeamHelp userTeamHelp;
    @Resource
    private DetailTabConfigService detailTabConfigService;
    @Resource
    private SearchCustomerCompanyModel searchCustomerCompanyModel;
    @Resource
    private PackageHelp packageHelp;
    @Resource
    private CustomerHelp customerHelp;
    @Resource
    private TagLinkModel tagLinkModel;
    @Resource
    private FeeLogModel feeLogModel;


    @Override
        public List<Integer> businessType() {
            return Arrays.asList(XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode());
        }


        @Override
        public void checkPermission(PaasFormEntityExt formEntity, PaasFormDataEntityExt paasFormDataEntityExt, UserVO loginUser, Integer subBusinessType) throws XbbException {
            if (loginUser.isMaxDataPermission()){
                return;
            }
            //校验用户是否有查看权限
            verifyQueryPermission(formEntity.getBusinessType(), loginUser, formEntity.getSaasMark(), formEntity.getMenuId(), paasFormDataEntityExt.getFlowStatus());
            //团队权限&共享权限校验
            customerPermissionService.checkPermission(formEntity, paasFormDataEntityExt, loginUser, subBusinessType);

            CrmPermissionUtil.checkData(paasFormDataEntityExt, subBusinessType);

        }


    @Override
    public List<ButtonPojo> handleDetailButton(FormDataDetailDTO formDataDetailDTO, HandelDetailPojo handelDetailPojo, PaasFormDataEntityExt paasFormDataEntityExt, Map<String, FieldAttrEntity> explainMap) throws XbbException {
        Integer businessType = handelDetailPojo.getBusinessType();
        String corpid = paasFormDataEntityExt.getCorpid();
        List<ButtonPojo> buttonPojoList = new ArrayList<>();
        Integer del = paasFormDataEntityExt.getDel();
        UserVO userVO = handelDetailPojo.getLoginUser();
        List<BusinessDetailButtonEnum> buttonEnumList = BusinessDetailButtonEnum.getByBusinessTypeAndPermission(businessType, userVO.getPermSet());
        JSONObject dataList = paasFormDataEntityExt.getData();
        Integer isPublic = getIntegerOrDefaultFromFormData(dataList, CustomerManagementEnum.IS_PUBLIC.getAttr(), BasicConstant.ZERO);
        Integer isArchived = getIntegerOrDefaultFromFormData(dataList, CustomerManagementEnum.IS_ARCHIVED.getAttr(), ArchivedEnum.UN_ARCHIVED.getCode());
        VerifyViewPermissionDTO verifyViewPermissionDTO = new VerifyViewPermissionDTO(userVO, paasFormDataEntityExt);
        boolean perTag = commonPermissionHelp.checkEditPermissionWithoutShareEdit(formDataDetailDTO, verifyViewPermissionDTO, explainMap);
        for (BusinessDetailButtonEnum buttonEnum : buttonEnumList) {
            if (Objects.equals(del, DelEnum.DELETE.getDel())) {
                // 客户回收站支持复制，其它的操作不支持
                continue;
            }
            if (Objects.equals(isPublic, BasicConstant.ONE) && (Objects.equals(buttonEnum, BusinessDetailButtonEnum.CUSTOMER_CANCEL_ARCHIVED) || Objects.equals(buttonEnum, BusinessDetailButtonEnum.CUSTOMER_ARCHIVED))) {
                continue;
            }
            if (Objects.equals(isArchived, ArchivedEnum.UN_ARCHIVED.getCode()) && Objects.equals(buttonEnum, BusinessDetailButtonEnum.CUSTOMER_CANCEL_ARCHIVED)) {
                continue;
            } else if (Objects.equals(isArchived, ArchivedEnum.ARCHIVED.getCode()) && Objects.equals(buttonEnum, BusinessDetailButtonEnum.CUSTOMER_ARCHIVED)) {
                continue;
            }
            ButtonPojo buttonPojo = new ButtonPojo();
            SaasButtonEnum saasButtonEnum = buttonEnum.getAnEnum();
            if (!perTag && Objects.equals(SaasButtonEnum.EDIT.getAttr(), saasButtonEnum.getAttr())) {
                continue;
            }
            BeanUtil.copyProperties(saasButtonEnum, buttonPojo);
            buttonPojo.setLinkBusinessType(buttonEnum.getLinkBusinessType());
            buttonPojoList.add(buttonPojo);
        }
        cloudCodeHelp.setCloudCodeDetailButton(corpid, userVO.getDynamicPermSet(), paasFormDataEntityExt.getAppId(), paasFormDataEntityExt.getFormId(), businessType, buttonPojoList, formDataDetailDTO.getPlatform());
        return buttonPojoList;
    }

    @Override
    public DetailTitlePojo handleDetailFocus(FormDataDetailDTO formDataDetailDTO,  Integer businessType, PaasFormDataEntityExt paasFormDataEntityExt, String userId) throws XbbException {
        String corpid = formDataDetailDTO.getCorpid();
        DetailTitlePojo detailTitlePojo = new DetailTitlePojo();
        detailTitlePojo.setSealPoJoList(new ArrayList<>());
        String pid = getPid(formDataDetailDTO, corpid, paasFormDataEntityExt);
        detailTitlePojo.setPid(pid);
        //关注
        boolean isCusShare;
        try {
            isCusShare = companyConfigModel.hasBeenEnable(corpid, CompanyConfigEnum.SHARE_FOCUS_CUSTOEMR.getAlias(), BasicConstant.IS_USE.toString());
        } catch (XbbException e) {
            isCusShare = Objects.equals(CompanyConfigEnum.SHARE_FOCUS_CUSTOEMR.getValue(), BasicConstant.IS_USE.toString());
        }
        Map<String, Object> map = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        map.put("corpid", corpid);
        if (!isCusShare) {
            map.put("userId", userId);
        }
        Long id = paasFormDataEntityExt.getId();
        map.put("customerIdIn", Collections.singletonList(id));
        map.put("del", DelEnum.NORMAL.getDel());
        map.put("focus", BasicConstant.IS_USE);
        List<CustomerFocusEntity> customerFocusEntityList = customerFocusModel.findEntitys(map);
        Integer isFocus = customerFocusEntityList != null && customerFocusEntityList.size() > 0 ? BasicConstant.IS_USE : BasicConstant.NO_USE;

        detailTitlePojo.setIsFocus(isFocus);
        return detailTitlePojo;
    }



    @Override
    public List<WorkFlowPojo> webHandleDetailWorkFlow(HandelDetailPojo handelDetailPojo, PaasFormEntityExt formEntity, PaasFormDataEntityExt paasFormDataEntityExt) throws XbbException {
        UserVO userVO = handelDetailPojo.getLoginUser();
        Integer businessType = handelDetailPojo.getBusinessType();
        List<WorkFlowEnum> workFlowEnumList = WorkFlowEnum.getByBusinessTypeAndPermission(handelDetailPojo.getBusinessType(), userVO.getPermSet());
        String corpid = userVO.getCorpid();
        JSONObject dataList = paasFormDataEntityExt.getData();
        List<WorkFlowPojo> list = new ArrayList<>();
        Integer isPublic = getIntegerOrDefaultFromFormData(dataList, CustomerManagementEnum.IS_PUBLIC.getAttr(), BasicConstant.ZERO);
        Integer del = paasFormDataEntityExt.getDel();
        //工单未开，以及没有可以用的工单模板，移除关联新建工单
        boolean workOrderEnable = paasAppModel.validateAppEnable(null, XbbRefTypeEnum.WORK_ORDER.getAlias(), SaasMarkEnum.SAAS.getCode(), corpid);
        List<WorkOrderFormEntity>  workOrderEnableForms = workOrderFormModel.getTemplateWithPermission(corpid, userVO, null, null);
        if (!workOrderEnable || CollectionUtils.isEmpty(workOrderEnableForms)) {
            workFlowEnumList.remove(WorkFlowEnum.CUSTOMER_WORK_ORDER);
        }
        boolean workOrderV2Enable = paasAppModel.validateAppEnable(null, XbbRefTypeEnum.WORK_ORDER_V2_CENTER.getAlias(), SaasMarkEnum.SAAS.getCode(), corpid);
        boolean pastDue = feeLogModel.workOrderV2PastDue(corpid);
        if (!workOrderV2Enable || pastDue) {
            // 移除掉过期或者没开启的工单
            workFlowEnumList.remove(WorkFlowEnum.CUSTOMER_WORK_ORDER_V2);
        }

        // 获取对应businessType的alias
        List<String> aliasIn = WorkFlowEnum.getAliasIn(workFlowEnumList);

        Map<Integer, String> paasBusinessTypeToName = paasMenuModel.getMenuNameByAlias(aliasIn, corpid, businessType);
        Long nowModelType = fundSetModel.getModelType(corpid,XbbRefTypeEnum.CRM);
        for (WorkFlowEnum workFlowEnum : workFlowEnumList) {
            if (Objects.equals(isPublic, BasicConstant.ONE) || Objects.equals(del, DelEnum.DELETE.getDel())) {
                continue;
            }
            if (Objects.equals(workFlowEnum, WorkFlowEnum.CUSTOMER_PAYMENT) && !Objects.equals(nowModelType, ModelTypeEnum.PLAN.getCode())) {
                continue;
            }
            //如果团队内没有可退回的人员，则不展示回退公海池按钮
            if(Objects.equals(workFlowEnum, WorkFlowEnum.CUSTOMER_BACK_SEA) || Objects.equals(workFlowEnum, WorkFlowEnum.CLUE_BACK_SEA)){
                boolean canBackPublic = checkCanBackPublic(dataList, userVO);
                if(!canBackPublic){
                    continue;
                }
            }
            WorkFlowPojo workFlowPojo = new WorkFlowPojo();
            BeanUtil.copyProperties(workFlowEnum, workFlowPojo);
            workFlowPojo.setId(workFlowEnum.getAttr());
            NameUtil.changeValue(paasBusinessTypeToName, workFlowPojo);
            list.add(workFlowPojo);
        }
        List<LinkListPojo> linkList = JSONArray.parseArray(formEntity.getAssociationList(), LinkListPojo.class);
        list.addAll(linkListService.getCommonButton(linkList, paasFormDataEntityExt.getDel(), handelDetailPojo.getLoginUser(), paasFormDataEntityExt.getAppId(), paasFormDataEntityExt.getFormId(), handelDetailPojo.getBusinessType(), SaasMarkEnum.SAAS.getCode(), corpid));
        return list;
    }

    @Override
    public List<TopPermissionsPoJo> dingtalkHandleDetailWorkFlow(HandelDetailPojo handelDetailPojo, PaasFormEntityExt formEntity, PaasFormDataEntityExt formData, Map<String, FieldAttrEntity> explainMap) throws XbbException {
        // todo
        String corpid = formEntity.getCorpid();
        UserVO userVO = handelDetailPojo.getLoginUser();
        Integer businessType = formEntity.getBusinessType();
        JSONObject dataList = formData.getData();
        List<WorkFlowEnum> workFlowEnumList = WorkFlowEnum.getByBusinessTypeAndPermissionForDingtalk(businessType, userVO.getPermSet());
        boolean workOrderV2Enable = paasAppModel.validateAppEnable(null, XbbRefTypeEnum.WORK_ORDER_V2_CENTER.getAlias(), SaasMarkEnum.SAAS.getCode(), corpid);
        boolean pastDue = feeLogModel.workOrderV2PastDue(corpid);
        if (!workOrderV2Enable || pastDue) {
            // 移除掉过期或者没开启的工单
            workFlowEnumList.remove(WorkFlowEnum.CUSTOMER_WORK_ORDER_V2);
        }
        List<String> aliasIn = new ArrayList<>();
        workFlowEnumList.forEach(item -> aliasIn.add(XbbRefTypeEnum.getByCode(item.getBusinessType()).getAlias()));
        Map<Integer, String> paasBusinessTypeToName = paasMenuModel.getMenuNameByAlias(aliasIn, corpid, businessType);
        Long nowMmodelType = fundSetModel.getModelType(corpid,XbbRefTypeEnum.CRM);

        List<TopPermissionsPoJo> topPermissions = businessButtonService.dingtalkDetailCommon(userVO, formEntity, explainMap, formData);
        Integer isArchived = getIntegerOrDefaultFromFormData(dataList, CustomerManagementEnum.IS_ARCHIVED.getAttr(), ArchivedEnum.UN_ARCHIVED.getCode());
        Integer isPublic = getIntegerOrDefaultFromFormData(dataList, CustomerManagementEnum.IS_PUBLIC.getAttr(), BasicConstant.ZERO);
        Integer del = formData.getDel();
        if (Objects.equals(del, DelEnum.DELETE.getDel())) {
            topPermissions.removeIf(pojo-> Objects.equals(pojo.getAttr(), OperateTypeEnum.DELETE.getAlias())
                    || Objects.equals(pojo.getAttr(), OperateTypeEnum.EDIT.getAlias()));
        }
        for (WorkFlowEnum workFlowEnum : workFlowEnumList) {
//            if (!hasUpdate && (Objects.equals(workFlowEnum, WorkFlowEnum.CUSTOMER_ARCHIVED) || Objects.equals(workFlowEnum, WorkFlowEnum.CUSTOMER_CANCEL_ARCHIVED))) {
//                continue;
//            }
            //如果团队内没有可退回的人员，则不展示回退公海池按钮
            if(Objects.equals(workFlowEnum, WorkFlowEnum.CUSTOMER_BACK_SEA) || Objects.equals(workFlowEnum, WorkFlowEnum.CLUE_BACK_SEA)){
                boolean canBackPublic = checkCanBackPublic(dataList, userVO);
                if(!canBackPublic){
                    continue;
                }
            }
            if (Objects.equals(isArchived, ArchivedEnum.ARCHIVED.getCode()) && Objects.equals(workFlowEnum, WorkFlowEnum.CUSTOMER_ARCHIVED)) {
                continue;
            } else if (Objects.equals(isArchived, ArchivedEnum.UN_ARCHIVED.getCode()) && Objects.equals(workFlowEnum, WorkFlowEnum.CUSTOMER_CANCEL_ARCHIVED)) {
                continue;
            }
            if (Objects.equals(isPublic, BasicConstant.ONE) || Objects.equals(del, DelEnum.DELETE.getDel())) {
                continue;
            }
            if (Objects.equals(workFlowEnum, WorkFlowEnum.CUSTOMER_PAYMENT) && !Objects.equals(nowMmodelType, ModelTypeEnum.PLAN.getCode())) {
                continue;
            }
            TopPermissionsPoJo topPermissionsPoJo = new TopPermissionsPoJo();
            BeanUtil.copyProperties(workFlowEnum, topPermissionsPoJo);
            if (Objects.equals(workFlowEnum.getFormRelation(), BasicConstant.ONE)) {
                NameUtil.changeValue(paasBusinessTypeToName, topPermissionsPoJo);
            }
            topPermissions.add(topPermissionsPoJo);
        }
        List<LinkListPojo> linkList = formEntity.getLinkListList();
        topPermissions.addAll(linkListService.getDingtalkCommonButton(linkList, formData.getDel(), userVO, formData.getAppId(), formData.getFormId(), businessType, formEntity.getSaasMark(), corpid));
        return topPermissions;
    }

    @Override
    public DataDetailPojo handleDetailData(Integer businessType, PaasFormDataEntityExt paasFormDataEntityExt, String userId, HandlerExplainDTO handlerExplainDTO) throws XbbException {
        DataDetailPojo dataDetailPojo = new DataDetailPojo();
        handlerExplainDTO.setCreatorId(paasFormDataEntityExt.getData().getString(CustomerManagementEnum.CREATOR.getAttr()));
        String corpid = handlerExplainDTO.getCorpid();
        Long formId = paasFormDataEntityExt.getFormId();

        Map<String, FieldAttrEntity> explainMap = ExplainUtil.getExplainMapByList(handlerExplainDTO.getExplainList());
        // 呼叫中心权限
        boolean isActiveCall = callCenterService.isOpenCallAndAgent( corpid, userId);
        List<DetaPhonePojo> dial = new ArrayList<>();
        if ( isActiveCall ) {
            dial = callCenterService.cusCallPhone(paasFormDataEntityExt.getData(), businessType, corpid, explainMap, handlerExplainDTO);
        }
        // 呼叫中心号码
        dataDetailPojo.setDial(dial);
        //阿里云呼叫中心权限
        boolean isActiveAliyunCall = callCenterService.isActiveAliyunCall(corpid, userId).IsActiveAliyunAndHasRole();
        if ( isActiveAliyunCall ) {
            List<DetaPhonePojo> aliyunCallCenterDial = callCenterService.cusCallPhone(paasFormDataEntityExt.getData(), businessType, corpid, explainMap, handlerExplainDTO);
            if(CollectionUtils.isNotEmpty(aliyunCallCenterDial) && StringUtil.isNotEmpty(aliyunCallCenterDial.get(0).getPhoneNum())){
                dataDetailPojo.setAliyunCallCenterDial(aliyunCallCenterDial);
            }
        }
        // 外链
        Integer outerLinkShare = setOuterLinkShare(corpid, formId);
        dataDetailPojo.setHasOuterLinkShare(outerLinkShare);
        return dataDetailPojo;
    }

    @Override
    public JSONObject analysisData(PaasFormDataEntityExt paasFormDataEntityExt, HandlerExplainDTO handlerExplainDTO, HandlerExplainVO handlerExplainVO) throws XbbException{
        String corpid = handlerExplainDTO.getCorpid();
        Integer businessType = handlerExplainDTO.getBusinessType();
        Long formId = paasFormDataEntityExt.getFormId();
        List<FieldAttrEntity> list = handlerExplainVO.getHeadList();
        Map<String, FieldAttrEntity> explainMap = new HashMap<>(list.size());
        list.forEach(item->explainMap.put(item.getAttr(), item));

        ParseSingleRowDataVO parseSingleRowDataVO = commonAnalysisData(paasFormDataEntityExt, handlerExplainDTO, handlerExplainVO, list, explainMap);
        JSONObject data = parseSingleRowDataVO.getResult();
        handleDetailSpecialField(paasFormDataEntityExt, data, explainMap, handlerExplainDTO);

        //处理千分位
        FormDataGetVO formDataGetVO = new FormDataGetVO();
        formDataGetVO.setData(data);
        formDataGetAnalysisDataHelp.analysisGetOfThousandBits(formDataGetVO, list, false);
        return data;
    }

    @Override
    public void handleDetailSpecialField(PaasFormDataEntityExt formData, JSONObject data, Map<String, FieldAttrEntity> explainMap, HandlerExplainDTO handlerExplainDTO) throws XbbException {
        String corpid = handlerExplainDTO.getCorpid();
        Integer businessType = handlerExplainDTO.getBusinessType();
        Long formId = formData.getFormId();
        FormConfigGetDTO formConfigGetDTO = new FormConfigGetDTO();
        formConfigGetDTO.setCorpid(corpid);
        formConfigGetDTO.setBusinessType(businessType);
        formConfigGetDTO.setFormId(formId);
        Map<String, String> lastConnectTimeMap = formDataListAnalysisDataHelp.lastConnectTime(formConfigGetDTO);
        String lastConnectTime = lastConnectTimeMap.get(FormConfigEnum.CUSTOMER_LAST_CONNECT_TIME.getConfig());
        Long customerLastTime = FastJsonHelper.getLongFromFormData(data, CustomerManagementEnum.LAST_CONNECT_TIME.getAttr());
        if(lastConnectTime != null){
            String time = Objects.equals(lastConnectTime, "1") ? DateTimeUtil.getLastConnectTimeStr(customerLastTime) : DateUtil.getString(customerLastTime * 1000L, DateUtil.SDFYMDHM);
            data.put(CustomerManagementEnum.LAST_CONNECT_TIME.getAttr(), time);
        }
    }

    @Override
    public List<SummaryDataPoJo> getSummaryList(FormDataDetailDTO formDataDetailDTO, PaasFormDataEntityExt formData, PaasFormEntityExt formEntity, List<FieldAttrEntity> list, Map<String, FieldAttrEntity> explainMap, JSONObject data) throws XbbException {
        String corpid = formDataDetailDTO.getCorpid();
        Long dataId = formDataDetailDTO.getDataId();
        List<SummaryDataPoJo> summaryList = getCommonSummaryList(formData, formEntity, list, explainMap, data);

        Map<Long,String> publicTagMap = tagLinkModel.getPublicTag(corpid, Arrays.asList(dataId));
        if (Objects.nonNull(publicTagMap) && publicTagMap.containsKey(dataId)){
            SummaryDataPoJo summaryDataPoJo = new SummaryDataPoJo();
            summaryDataPoJo.setAttr(TagEnum.TAG_RETURN_PUBLIC.getAttr());
            summaryDataPoJo.setAttrName(I18nMessageUtil.getMessage(StringConstant.RETURN_PUBLIC));
            String memo = publicTagMap.get(dataId);
            summaryDataPoJo.setValue(Arrays.asList(memo));
            summaryList.add(summaryDataPoJo);
        }
        //客户详情 转移标签
        Map<Long,String> transferTagMap = tagLinkModel.getTransferTag(corpid, Arrays.asList(dataId),XbbRefTypeEnum.CUSTOMER_TRANSFER.getCode());
        if (Objects.nonNull(transferTagMap) && transferTagMap.containsKey(dataId)){
            SummaryDataPoJo summaryDataPoJo = new SummaryDataPoJo();
            summaryDataPoJo.setAttr(TagEnum.TAG_TRANSFER_PUBLIC_CUSTOMER.getAttr());
            summaryDataPoJo.setAttrName(I18nMessageUtil.getMessage(StringConstant.TRANSFER_PUBLIC));
            String memo = transferTagMap.get(dataId);
            summaryDataPoJo.setValue(Arrays.asList(memo));
            summaryList.add(summaryDataPoJo);
        }

        return summaryList;
    }


    /**
     * 摘要公共方法，手机端和pc端都会调，如有改动，都要覆盖测试
     * @param formData
     * @param formEntity
     * @param list
     * @param explainMap
     * @param data
     * @return
     * @throws XbbException
     */
    private List<SummaryDataPoJo> getCommonSummaryList(PaasFormDataEntityExt formData, PaasFormEntityExt formEntity, List<FieldAttrEntity> list, Map<String, FieldAttrEntity> explainMap, JSONObject data) throws XbbException {
        List<SummaryDataPoJo> summaryList = ExplainUtil.getSpecialSummaryList(formEntity.getSummaryList(), data, explainMap, formData);
        //客户公海池特殊处理 负责人->前负责人
        changeOwnerIdAttrName(data, summaryList);

        return summaryList;
    }


    @Override
    public JSONArray getSecondTitleList(FormDataDetailDTO formDataDetailDTO, PaasFormDataEntityExt formData, PaasFormEntityExt formEntity, List<FieldAttrEntity> list, Map<String, FieldAttrEntity> explainMap, JSONObject data) throws XbbException {
        String corpid = formDataDetailDTO.getCorpid();
        Long dataId = formData.getId();
        List<SummaryDataPoJo> summaryList = getCommonSummaryList( formData, formEntity, list, explainMap, data);
        JSONArray secondTitle = getSecondTitleList(summaryList, data, formDataDetailDTO.getCorpid(), formEntity.getId());

        String cStayTimeStr = stageAverageStayTimeHelp.getAverageStayTime(formDataDetailDTO.getSaasMark(), formDataDetailDTO.getBusinessType(), corpid, formEntity.getId(), dataId, formData.getData());

//                    String cStayTimeStr = customerStageLogModel.getAverageStayTime(corpid, dataId);
        if (cStayTimeStr != null) {
            JSONObject cusObj3 = ExplainUtil.getSecondTitleObj(false, I18nMessageUtil.getMessage(I18nStringConstant.CURRENT_STAGE_LONG), cStayTimeStr);
            secondTitle.add(cusObj3);
        }
        return secondTitle;
    }

    @Override
    public List<SummaryDataPoJo> getLabelList(FormDataDetailDTO formDataDetailDTO, PaasFormDataEntityExt formData, PaasFormEntityExt formEntity, List<FieldAttrEntity> explainList, Map<String, FieldAttrEntity> explainMap, JSONObject data) throws XbbException {
        // 解析标签
        List<SummaryDataPoJo> labelsList = ExplainUtil.getSpecialSummaryList(formEntity.getLabelsList(), data, explainMap, formData);
        //客户公海池特殊处理 负责人->前负责人
        changeOwnerIdAttrName(data, labelsList);
        return labelsList;
    }

    @Override
    public JSONArray getTagList(FormDataDetailDTO formDataDetailDTO, PaasFormDataEntityExt formData, PaasFormEntityExt formEntity, List<FieldAttrEntity> list, Map<String, FieldAttrEntity> explainMap, JSONObject data) throws XbbException {
        String corpid = formDataDetailDTO.getCorpid();
        Integer businessType = formEntity.getBusinessType();
        Long dataId = formData.getId();
        String userId = formDataDetailDTO.getUserId();
        List<SummaryDataPoJo> labelsList = getLabelList(formDataDetailDTO, formData, formEntity, list, explainMap, data);
        JSONArray tags = getTags(labelsList, corpid, businessType, dataId, userId);
        return tags;
    }

    @Override
    public List<FormTitlePoJo> getTitleList(FormDataDetailDTO formDataDetailDTO, PaasFormDataEntityExt formData, PaasFormEntityExt formEntity, List<FieldAttrEntity> explainList, Map<String, FieldAttrEntity> explainMap, JSONObject data) throws XbbException {

        return ExplainUtil.getSpecailFormTitle(JSONArray.parseArray(formEntity.getCustomTitle()), explainMap, data, explainList, formData);
    }

    @Override
    public String getTitle(FormDataDetailDTO formDataDetailDTO, PaasFormDataEntityExt formData, PaasFormEntityExt formEntity, List<FieldAttrEntity> list, Map<String, FieldAttrEntity> explainMap, JSONObject data) throws XbbException {
        List<FormTitlePoJo> formTitleList = getTitleList(formDataDetailDTO, formData, formEntity, list, explainMap, data);
        return TitleUtil.getWebTitle(formTitleList);
    }

    @Override
    public List<DetailTabPojo> handleDetailTab(HandelDetailPojo handelDetailPojo, PaasFormEntityExt formEntity, PaasFormDataEntityExt paasFormDataEntityExt, Map<String, FieldAttrEntity> explainMap, HandlerExplainVO handlerExplainVO, HandlerExplainDTO handlerExplainDTO) throws XbbException {
        UserVO userVO = handelDetailPojo.getLoginUser();
        String corpid = userVO.getCorpid();
        String userId = userVO.getUserId();
        Integer businessType = handelDetailPojo.getBusinessType();
        List<DetailTabPojo> tabPojoList = new ArrayList<>();
        String creatorId = FastJsonHelper.getStringOrDefaultFromFormData(paasFormDataEntityExt.getData(), CustomerManagementEnum.CREATOR.getAttr(), "");
        if (StringUtil.isNotEmpty(creatorId)) {
            // 客户创建人用逻辑创建人
            handlerExplainDTO.setCreatorId(creatorId);
        }
        Integer isPublic = getIntegerOrDefaultFromFormData(paasFormDataEntityExt.getData(), CustomerManagementEnum.IS_PUBLIC.getAttr(), BasicConstant.ZERO);
        // 查询此客户关联的退货退款
        Map<String, Object> modelMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        modelMap.put(ParameterConstant.CORPID, corpid);
        modelMap.put(ParameterConstant.DEL, DelEnum.NORMAL.getDel());
        Map<String, Object> dataParam = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        dataParam.put(RefundEnum.CUSTOMER_ID.getAttr(), paasFormDataEntityExt.getId());
        List<PaasFormDataEntityExt> paasFormDataEntityExts = paasEsModel.selectByCondition(XbbRefTypeEnum.REFUND.getCode(), dataParam, modelMap, IndexTypeEnum.IDX_SAAS_REFUND);
        //判断客户阶段是否开启
        boolean ifCustomerStageOpen = CommonHelp.ifStageOpen(businessType, explainMap, handlerExplainDTO);
        PaasMenuEntity customerQuotation = paasMenuModel.getByAlias(XbbRefTypeEnum.QUOTATION.getAlias(), null, corpid);
        boolean cusQuotationShow = customerQuotation != null && Objects.equals(customerQuotation.getEnable(), BasicConstant.ONE);
        // 判断电话字段是否可见
        boolean customerMobile = commonHelp.attrCanSee(CustomerManagementEnum.PHONE.getAttr(), explainMap, handlerExplainDTO);
        if(customerMobile){
            List<? extends FieldAttrEntity> explainSubFormList = explainMap.get(CustomerManagementEnum.PHONE.getAttr()).getSubForm().getItems();
            Map<String, FieldAttrEntity> explainSubFormMap = new HashMap<>(explainSubFormList.size());
            explainSubFormList.forEach((item) -> explainSubFormMap.put(item.getAttr(), item));
            boolean text2CanSee = commonHelp.attrCanSee(StringConstant.PHONE_TEL_ATTR, explainSubFormMap, handlerExplainDTO);
            if(!text2CanSee){
                customerMobile = false;
            }
        }
        // 判断当前公司有没有开启呼叫中心
        boolean isActiveCall = callCenterService.isOpenCallAndAgent(corpid, userId);
        List<BusinessDetailTabEnum> tabEnumList = BusinessDetailTabEnum.getTabByBusinessTypeAndPermission(businessType, userVO.getPermSet(), handlerExplainDTO.getPlatform());
        boolean isActiveAliyunCall = callCenterService.isActiveAliyunCall(corpid, userId).IsActiveAliyunAndHasRole();

        // 兼容原呼叫中心  开通了其中一个就显示 通话记录tab
        isActiveCall = isActiveCall||isActiveAliyunCall;
        // 判断应用是否启用
        boolean isSmsUse = paasAppModel.validateAppEnable(null, XbbRefTypeEnum.GROUP_MESSAGE.getAlias(), 1, corpid);
        // 判断当前员工有没有短信权限
        boolean canSms = isSmsUse && userVO.getPermSet().contains(ProPermissionAliasEnum.SMS_VIEW.getAlias());
        // 套餐类型
        Integer feeType = packageHelp.getFeeType(corpid);
        // 旗舰版
        boolean ultimateType = Objects.equals(PackageTypeEnum.ULTIMATE.getType(), feeType);

        boolean parentCustomer = commonHelp.attrCanSee(CustomerManagementEnum.PARENT.getAttr(), explainMap, handlerExplainDTO);
        // 获取对应businessType的alias
        List<String> aliasIn = BusinessDetailTabEnum.getAliasIn(tabEnumList);

        // 记录businessType与menuName的关系
        Map<Integer, String> paasBusinessTypeToName = paasMenuModel.getMenuNameByAlias(aliasIn, corpid, businessType);

        for (BusinessDetailTabEnum tabEnum : tabEnumList) {
            // 移动端不需要阶段历史
            if (Objects.equals(tabEnum, BusinessDetailTabEnum.CUSTOMER_CUSTOMER_STAGE) && Objects.equals(handlerExplainDTO.getPlatform(), PlatFormEnum.DINGTALK.getValue())) {
                continue;
            }
            if (Objects.equals(isPublic, 1) && Objects.equals(tabEnum, BusinessDetailTabEnum.CUSTOMER_SALE_TEAM)) {
                continue;
            }
            if (!isActiveCall && Objects.equals(tabEnum, BusinessDetailTabEnum.CUSTOMER_CALL_LOG)) {
                continue;
            }
            if (paasFormDataEntityExts.isEmpty() && Objects.equals(tabEnum, BusinessDetailTabEnum.CUSTOMER_REFUND)) {
                continue;
            }
            if (Objects.equals(tabEnum, BusinessDetailTabEnum.CUSTOMER_CUSTOMER_STAGE) && !ifCustomerStageOpen) {
                continue;
            }
            if (Objects.equals(tabEnum, BusinessDetailTabEnum.CUSTOMER_QUOTATTIO) && !cusQuotationShow) {
                continue;
            }
            if (!canSms && Objects.equals(tabEnum, BusinessDetailTabEnum.CUSTOMER_SMS_SEND_AND_REPLY)) {
                continue;
            }
            if (!parentCustomer && Objects.equals(tabEnum, BusinessDetailTabEnum.CUSTOMER_PARENT_AND_CHILD)) {
                continue;
            }
            // 短信往来tab
            if (!customerMobile && Objects.equals(tabEnum, BusinessDetailTabEnum.CUSTOMER_SMS_SEND_AND_REPLY)) {
                continue;
            }
            if ( !userVO.getPermSet().contains(ProPermissionAliasEnum.PAYMENT_SHEET_VIEW.getAlias()) && !userVO.getPermSet().contains(ProPermissionAliasEnum.PAYMENT_VIEW.getAlias()) && Objects.equals(tabEnum, BusinessDetailTabEnum.CUSTOMER_PAYMENT) ) {
                continue;
            }
            // 非旗舰版，移动端没有联系人组织树
            if (!ultimateType && Objects.equals(handlerExplainDTO.getPlatform(), PlatFormEnum.DINGTALK.getValue()) && Objects.equals(tabEnum, BusinessDetailTabEnum.CONTACT_ORGANIZATION_TREE)) {
                continue;
            }
            DetailTabPojo detailTabPojo = new DetailTabPojo();
            BeanUtil.copyProperties(tabEnum.getAnEnum(), detailTabPojo);
            detailTabPojo.setAttr(detailTabPojo.getKey());
            NameUtil.changeTabEnumName(paasBusinessTypeToName, tabEnum, detailTabPojo);
            //判断是否有回款单，是否有应收款、回款计划权限
            if ( Objects.equals(tabEnum, BusinessDetailTabEnum.CUSTOMER_PAYMENT) ) {
                Boolean isHasPayment = false;
                Boolean isHasPaymentSheet = false;
                if ( userVO.getPermSet().contains(ProPermissionAliasEnum.PAYMENT_SHEET_VIEW.getAlias()) ) {
                    isHasPaymentSheet = true;
                }
                if ( userVO.getPermSet().contains(ProPermissionAliasEnum.PAYMENT_VIEW.getAlias()) ) {
                    isHasPayment = true;
                }
                detailTabPojo.setIsHasPayment(isHasPayment);
                detailTabPojo.setIsHasPaymentSheet(isHasPaymentSheet);
            }
            // web端联系人和组织树使用同一个tab，特殊处理
            if (Objects.equals(tabEnum, BusinessDetailTabEnum.CUSTOMER_CONTACT_TAB)) {
                detailTabPojo.setIsHasContactTree(ultimateType);
            }
            tabPojoList.add(detailTabPojo);
        }
        handleTeamTab(tabPojoList, explainMap);
        List<LinkListPojo> linkList = JSONArray.parseArray(formEntity.getAssociationList(), LinkListPojo.class);
        handlerExplainVO.setAppId(formEntity.getAppId());
        handlerExplainVO.setFormId(formEntity.getId());
        // 公共tab
        tabPojoList.addAll(linkListService.commonTab(corpid, userVO, handlerExplainVO, handlerExplainDTO, businessType, paasFormDataEntityExt.getDel(), linkList));
        // tab排序
        tabPojoList = detailTabConfigService.handleDetailTabSort(userVO.getUserId(), corpid, handlerExplainVO.getFormId(), businessType, tabPojoList);

        return tabPojoList;
    }


    @Override
    public List<MobileDetailMoneyItemPojo> getMobileDetailMoneyInfo(Integer distributorMark, String corpid, String userId, Integer businessType, Integer subBusinessType, Long dataId, JSONObject data, Map<String, FieldAttrEntity> explainMap, UserVO loginUser, PaasFormDataEntityExt paasFormDataEntityExt) throws XbbException {
        List<MobileDetailMoneyItemPojo> moneyItemList = new ArrayList<>();
        Integer accuracy = 2;
        List<PaasFormDataEntityExt> customerCommunicateList = customerCommunicateModel.getCustomerCommunicateListByLinkId(corpid, dataId, CustomerCommunicateEnum.CUSTOMER_NAME, PaasFormDataEntityExt.class, "data." + CustomerCommunicateEnum.COMMUNICATE_TIME.getAttr(), SortOrder.DESC);
        Integer customerCommunicateCount = Objects.isNull(customerCommunicateList) ? 0 : customerCommunicateList.size();
        moneyItemList.add(new MobileDetailMoneyItemPojo(I18nMessageUtil.getMessage(I18nStringConstant.FOLLOW_UP_TIMES), customerCommunicateCount, false));
        FormDataListDTO formDataListDTO = new FormDataListDTO();
        formDataListDTO.setUserId(userId);
        formDataListDTO.setCorpid(corpid);
        formDataListDTO.setExplainMap(explainMap);
        List<PaasFormDataEntityExt> contractList = contractModel.getContractListByLinkId(corpid, dataId, ContractEnum.LINK_CUSTOMER, PaasFormDataEntityExt.class);
        // 客户需要查询出合同订单，销售机会，报价单这三个菜单的名称。
        Map<String, String> menuMap = customerHelp.getMenuMap(corpid);
        if (Objects.nonNull(contractList)) {
            AtomicReference<Double> totalAmount = new AtomicReference<>(0D);
            contractList.forEach(contract -> {
                JSONObject contractData = contract.getData();
                Double totalMoney = StringUtil.toDouble(contractData.getString(ContractEnum.AMOUNT.getAttr()), 0D);
                totalAmount.set(Arith.add(totalAmount.get(), totalMoney));
            });
            //订单金额处理为千份位
            Object orderAmount = AttrDecimalPrecisionHelper.parseThousandth(totalAmount.get(),accuracy);
            moneyItemList.add(new MobileDetailMoneyItemPojo(I18nMessageUtil.getMessage(I18nStringConstant.ORDER_AMOUNT),orderAmount, false));
            List<ConditionsEntityExt> contractCondictions = new ArrayList<>();
            ConditionsEntityExt contractCondiction = new ConditionsEntityExt(ContractEnum.LINK_CUSTOMER.getAttr(), "", ContractEnum.LINK_CUSTOMER.getFieldType(), ConditionEnum.EQUAL.getSymbol(), Collections.singletonList(dataId));
            contractCondictions.add(contractCondiction);
            contractCondictions.add(EsUtil.packageContions(ContractEnum.IS_RED.getAttr(), Collections.singletonList(0), ConditionEnum.EQUAL, ContractEnum.IS_RED.getFieldType()));
            String contractName = StringUtil.isEmpty(menuMap.get(XbbRefTypeEnum.CONTRACT.getAlias())) ? I18nMessageUtil.getMessage(I18nStringConstant.CONTRACT_ORDER) : menuMap.get(XbbRefTypeEnum.CONTRACT.getAlias());
            moneyItemList.add(new MobileDetailMoneyItemPojo(contractName, contractList.size(), contractCondictions, true, XbbRefTypeEnum.CONTRACT.getCode(), BasicConstant.ONE));
        }
        List<String> codeList = PaymentSheetTypeEnum.getCodeListForCustomerSum();
        List<PaasFormDataEntityExt> paymentSheets = paymentSheetModel.getPaymentSheetEsDataListByCustomerId(corpid, dataId, codeList, loginUser);
        if (Objects.nonNull(paymentSheets)) {
            AtomicReference<Double> paymentAmount = new AtomicReference<>(0D);
            paymentSheets.forEach(payment -> {
                JSONObject paymentData = payment.getData();
                Double totalMoney = StringUtil.toDouble(paymentData.getString(PaymentSheetEnum.AMOUNT.getAttr()), 0D);
                paymentAmount.set(Arith.add(paymentAmount.get(), totalMoney));
            });
            String paymentTotal = attrDecimalPrecisionHelper.formatMoneyPrecision(paymentAmount.get(), accuracy);
            List<ConditionsEntityExt> paymentCondictions = new ArrayList<>();
            ConditionsEntityExt paymentCondiction = new ConditionsEntityExt(PaymentSheetEnum.CUSTOMER_ID.getAttr(), "", PaymentSheetEnum.CUSTOMER_ID.getFieldType(), ConditionEnum.EQUAL.getSymbol(), Collections.singletonList(dataId));
            paymentCondictions.add(paymentCondiction);
            moneyItemList.add(new MobileDetailMoneyItemPojo(distributorMark, I18nMessageUtil.getMessage(I18nStringConstant.TOTAL_REFUND), paymentTotal, paymentCondictions,  true, XbbRefTypeEnum.PAYMENT_SHEET.getCode(), BasicConstant.ONE));
        }
        List<PaasFormDataEntityExt> opportunityList = opportunityModel.getOpportunityListByLinkId(corpid, dataId, SalesOpportunityEnum.CUSTOMER_NAME, PaasFormDataEntityExt.class);
        boolean opportunityMenuFlag = paasMenuModel.enableMenu(corpid, XbbRefTypeEnum.SALES_OPPORTUNITY.getAlias());
        if (Objects.nonNull(opportunityList) && opportunityMenuFlag) {
            List<ConditionsEntityExt> opportunityCondictions = new ArrayList<>();
            ConditionsEntityExt opportunityCondiction = new ConditionsEntityExt(SalesOpportunityEnum.CUSTOMER_NAME.getAttr(), "", SalesOpportunityEnum.CUSTOMER_NAME.getFieldType(), ConditionEnum.EQUAL.getSymbol(), Collections.singletonList(dataId));
            opportunityCondictions.add(opportunityCondiction);
            String opportunityName = StringUtil.isEmpty(menuMap.get(XbbRefTypeEnum.SALES_OPPORTUNITY.getAlias())) ? I18nMessageUtil.getMessage(I18nStringConstant.SALES_OPPORTUNITIES) : menuMap.get(XbbRefTypeEnum.SALES_OPPORTUNITY.getAlias());
            moneyItemList.add(new MobileDetailMoneyItemPojo(opportunityName, opportunityList.size(), opportunityCondictions, true, XbbRefTypeEnum.SALES_OPPORTUNITY.getCode(), BasicConstant.ONE));
        }
        List<PaasFormDataEntityExt> quotationList = quotationModel.getQuotationListByLinkId(corpid, dataId, QuotationEnum.CUSTOMER_ID, PaasFormDataEntityExt.class);
        boolean quotationMenuFlag = paasMenuModel.enableMenu(corpid, XbbRefTypeEnum.QUOTATION.getAlias());
        if (Objects.nonNull(quotationList) && quotationMenuFlag) {
            List<ConditionsEntityExt> quotationCondictions = new ArrayList<>();
            ConditionsEntityExt quotationCondiction = new ConditionsEntityExt(QuotationEnum.CUSTOMER_ID.getAttr(), "", QuotationEnum.CUSTOMER_ID.getFieldType(), ConditionEnum.EQUAL.getSymbol(), Collections.singletonList(dataId));
            ConditionsEntityExt newVersionCondiction = new ConditionsEntityExt(QuotationEnum.IS_NEW.getAttr(), "", QuotationEnum.IS_NEW.getFieldType(), ConditionEnum.EQUAL.getSymbol(), Collections.singletonList(BasicConstant.ONE));
            quotationCondictions.add(quotationCondiction);
            quotationCondictions.add(newVersionCondiction);
            String quotationName = StringUtil.isEmpty(menuMap.get(XbbRefTypeEnum.QUOTATION.getAlias())) ? I18nMessageUtil.getMessage(I18nStringConstant.QUOTATION) : menuMap.get(XbbRefTypeEnum.QUOTATION.getAlias());
            moneyItemList.add(new MobileDetailMoneyItemPojo(quotationName, quotationList.size(), quotationCondictions, true, XbbRefTypeEnum.QUOTATION.getCode(), BasicConstant.ONE));
        }
        //应收未收
        List<PaasFormDataEntityExt> paymentList = paymentModel.getPaymentEsDataListByLinkId(corpid,dataId, PaymentEnum.CUSTOMER, PaasFormDataEntityExt.class);
        AtomicReference<Double> paymentAmount = new AtomicReference<>(0D);
        paymentList.forEach(payment -> {
            JSONObject paymentData = payment.getData();
            Double totalMoney = StringUtil.toDouble(paymentData.getString(PaymentEnum.UN_AMOUNT.getAttr()), 0D);
            paymentAmount.set(Arith.add(paymentAmount.get(), totalMoney));
        });
        String paymentTotal = attrDecimalPrecisionHelper.formatMoneyPrecision(paymentAmount.get(), accuracy);
        List<ConditionsEntityExt> paymentCondictions = new ArrayList<>();
        ConditionsEntityExt paymentCondiction = new ConditionsEntityExt(PaymentEnum.CUSTOMER.getAttr(), "", PaymentEnum.CUSTOMER.getFieldType(), ConditionEnum.EQUAL.getSymbol(), Collections.singletonList(dataId));
        paymentCondictions.add(paymentCondiction);
        moneyItemList.add(new MobileDetailMoneyItemPojo(distributorMark, I18nMessageUtil.getMessage(I18nStringConstant.TOTAL_PAYMENT), paymentTotal, paymentCondictions,  true, XbbRefTypeEnum.PAYMENT.getCode(), BasicConstant.ONE));
        return moneyItemList;
    }


    @Override
    public JSONArray getBottomBlockInfo(String corpid, String userId, Integer businessType,  PaasFormEntityExt formEntity, Long dataId, JSONObject data, Map<String, FieldAttrEntity> explainMap, PaasFormDataEntityExt entityExt, HandlerExplainDTO handlerExplainDTO) throws XbbException {
        Integer isPublic = getIntegerOrDefaultFromFormData(data, CustomerManagementEnum.IS_PUBLIC.getAttr(), 0);
        JSONArray bottomBlockInfo = new JSONArray();
        if (!Objects.equals(isPublic, BasicConstant.ONE)) {
            List<CustomerUserPojo> userPojoList = new ArrayList<>();
            Map<String, UserEntity> userMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            List<String> userIdIn = new ArrayList<>();
            Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            param.put("corpid", corpid);
            param.put("del", 0);
            param.put("customerId", dataId);
            List<CustomerUserEntity> customerUserEntityList = customerUserModel.findEntitys(param);
            customerUserEntityList.forEach(item -> userIdIn.add(item.getUserId()));
            List<UserEntity> userEntityList = userModel.getByUserIdIn(corpid, userIdIn, true);
            userEntityList.forEach(item -> userMap.put(item.getUserId(), item));
            customerUserEntityList.forEach(item -> {
                UserEntity userEntity = userMap.get(item.getUserId());
                if (userEntity != null) {
                    CustomerUserPojo customerUserPojo = new CustomerUserPojo();
                    customerUserPojo.setUserId(userEntity.getUserId());
                    customerUserPojo.setName(userEntity.getName());
                    customerUserPojo.setAvatar(userEntity.getAvatar());
                    customerUserPojo.setIsMain(item.getIsMain());
                    userPojoList.add(customerUserPojo);
                }
            });
            bottomBlockInfo.add(new MobileDetailManagerBlockPojo(userPojoList));
        }
        Integer editAfterFinish = processFieldHelp.isEditable(corpid, explainMap, entityExt.getAppId(), entityExt.getFormId(), entityExt.getFlowStatus(), CustomerManagementEnum.TYPE.getAttr(), handlerExplainDTO);
        bottomBlockInfo.add(getMobileDetailStatusBlockPojo(corpid, entityExt.getData(), DictionaryEnum.CUSTOMER_STATUS, CustomerManagementEnum.TYPE.getAttr(), editAfterFinish));
        return bottomBlockInfo;
    }

    @Override
    public MobileDetailSpecialInfoPojo getMobileDetailSpecialInfo(FormDataDetailDTO formDataDetailDTO, PaasFormDataEntityExt paasFormDataEntityExt, Map<String, FieldAttrEntity> explainMap) throws XbbException {
        String corpid = formDataDetailDTO.getCorpid();
        Integer businessType = formDataDetailDTO.getBusinessType();
        MobileDetailSpecialInfoPojo mobileDetailSpecialInfoPojo = super.getMobileDetailSpecialInfo(formDataDetailDTO, paasFormDataEntityExt, explainMap);
        // 评分
        mobileDetailSpecialInfoPojo.setScore(scoreRangeModel.getScoreShowValue(businessType,paasFormDataEntityExt));
        // 栗子图标
        String pid = getPid(formDataDetailDTO, corpid, paasFormDataEntityExt);
        Map<String, Object> operation = mobileDetailSpecialInfoPojo.getOperation();
        operation.put("pid", pid);
        mobileDetailSpecialInfoPojo.setOperation(operation);
        return mobileDetailSpecialInfoPojo;
    }

    @Override
    public List<MobileDetailScriptPojo> getDetailShowScript(Integer businessType, UserVO loginUser, PaasFormDataEntityExt paasFormDataEntityExt, Map<String, FieldAttrEntity> explainMap) throws XbbException {
        return new ArrayList<>();
    }

    @Override
    public MobileDetailStatusPojo getDetailShowStatus(Integer businessType, JSONObject data) throws XbbException {
        MobileDetailStatusPojo mobileDetailStatusPojo = new MobileDetailStatusPojo();
        Integer isArchived = getIntegerOrDefaultFromFormData(data, CustomerManagementEnum.IS_ARCHIVED.getAttr(), 2);
        mobileDetailStatusPojo.setName("archived");
        mobileDetailStatusPojo.setValue(isArchived);
        return mobileDetailStatusPojo;
    }

    @Override
    public Map<String, Object> getDetailShowOperation(String corpid, String userId, Integer businessType, Long dataId, JSONObject data) throws XbbException {
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        //关注
        boolean isCusShare;
        try {
            isCusShare = companyConfigModel.hasBeenEnable(corpid, CompanyConfigEnum.SHARE_FOCUS_CUSTOEMR.getAlias(), BasicConstant.IS_USE.toString());
        } catch (XbbException e) {
            isCusShare = Objects.equals(CompanyConfigEnum.SHARE_FOCUS_CUSTOEMR.getValue(), BasicConstant.IS_USE.toString());
        }
        Map<String, Object> map = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        map.put("corpid", corpid);
        if(!isCusShare) {
            map.put("userId", userId);
        }
        map.put("customerIdIn", Collections.singletonList(dataId));
        map.put("del", DelEnum.NORMAL.getDel());
        map.put("focus", BasicConstant.IS_USE);
        List<CustomerFocusEntity> customerFocusEntityList = customerFocusModel.findEntitys(map);
        Integer isFocus = customerFocusEntityList != null && customerFocusEntityList.size() > 0 ? BasicConstant.IS_USE : BasicConstant.NO_USE;
        //有提醒的客户
        List<Long> pushNotifyList = new ArrayList<>();
        pushModel.getPushNotify(Collections.singletonList(dataId), corpid, XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), pushNotifyList);
        if (!pushNotifyList.isEmpty()) {
            param.put("message", true);
        }
        param.put("isFocus", isFocus);
        return param;
    }

    @Override
    public void returnVO(PaasFormEntityExt formEntity, PaasFormDataEntityExt paasFormDataEntityExt, MobileFormCommonDetailVO mobileFormCommonDetailVO, String userId) throws XbbException {
//默认非公海
        Integer isPublic = 0;
        JSONObject data = paasFormDataEntityExt.getData();
        if ( data.containsKey(CustomerManagementEnum.IS_PUBLIC.getAttr()) ) {
            isPublic = data.getInteger(CustomerManagementEnum.IS_PUBLIC.getAttr());
        }
        mobileFormCommonDetailVO.setIsPublic(isPublic);
        mobileFormCommonDetailVO.setDistributorMark(formEntity.getDistributorMark());
        mobileFormCommonDetailVO.setPaasFormEntity(formEntity);
        mobileFormCommonDetailVO.setHasOuterLinkShare(setOuterLinkShare(formEntity.getCorpid(), formEntity.getId()));
        //判断老搜客能否使用，只客户业务详情页添加老搜索标识
        SearchCustomerCompanyEntity byCorpid = searchCustomerCompanyModel.getByCorpid(paasFormDataEntityExt.getCorpid(), SoukeMealEnum.SOUKE.getType());
        if (Objects.nonNull(byCorpid) && byCorpid.getExtraExpiry() > DateUtil.getInt()){
            mobileFormCommonDetailVO.setIsBusiness(1);
        }
        //判断工商查询能否使用
        if (fineClueHelp.isFineClueByCorpid(paasFormDataEntityExt.getCorpid(), XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), formEntity.getDistributorMark())) {
            mobileFormCommonDetailVO.setIsFineClue(1);
        }
    }

    @Override
    public List<TopPermissionsPoJo> getMobileDetailBottomOperation(HandelDetailPojo handelDetailPojo, PaasFormEntityExt formEntity, PaasFormDataEntityExt paasFormDataEntityExt, HandlerExplainDTO handlerExplainDTO, Map<String, FieldAttrEntity> explainMap) throws XbbException {
        Integer businessType = handelDetailPojo.getBusinessType();
        Integer businessType4Distributor = XbbRefTypeEnum.transferBusinessType4Distributor(businessType, handelDetailPojo.getDistributorMark());
        UserVO userVO = handelDetailPojo.getLoginUser();
        List<TopPermissionsPoJo> bottomOperationList = new ArrayList<>();
        List<MobileDetailBottomOperationEnum> bottomOperationEnumList = MobileDetailBottomOperationEnum.getByBusinessTypeAndPermission(businessType4Distributor, userVO.getPermSet());
        for (MobileDetailBottomOperationEnum anEnum : bottomOperationEnumList) {
            TopPermissionsPoJo topPermissionsPoJo = new TopPermissionsPoJo();
            BeanUtil.copyProperties(anEnum, topPermissionsPoJo);
            bottomOperationList.add(topPermissionsPoJo);
        }
        return bottomOperationList;
    }

    @Override
    public JSONObject returnSaasObject(String corpid, Integer businessType, UserVO userVO, PaasFormDataEntityExt paasFormDataEntityExt) throws XbbException {
        JSONObject saasReturnObj = new JSONObject();
        //快捷新建跟进记录tab栏显示与否
        saasReturnObj.put(StringConstant.QUICKFLLOWTAB, true);
        //客户动态显示与否
        saasReturnObj.put(StringConstant.DYNAMIC, true);
        //动态名称
        saasReturnObj.put(StringConstant.DYNAMICNAME, I18nMessageUtil.getMessage(I18nStringConstant.CUSTOMER_DYNAMIC));
        return saasReturnObj;
    }


    @Override
    protected void setFormEntity(FormDataDetailDTO formDataDetailDTO, PaasFormEntityExt form, FormDataDetailVO formDataDetailVO) {
        formDataDetailVO.setPaasFormEntityExt(form);
        //判断老搜客能否使用
        SearchCustomerCompanyEntity byCorpid = searchCustomerCompanyModel.getByCorpid(formDataDetailDTO.getCorpid(), SoukeMealEnum.SOUKE.getType());
        if (Objects.nonNull(byCorpid) && byCorpid.getExtraExpiry() > DateUtil.getInt()){
            formDataDetailVO.setIsBusiness(1);
        }
        //判断工商查询能否使用
        if (fineClueHelp.isFineClueByCorpid(formDataDetailDTO.getCorpid(), XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), formDataDetailDTO.getDistributorMark())) {
            formDataDetailVO.setIsFineClue(1);
        }
    }

    /**
     * 将公海池的负责人改为前负责人
     * @param data
     * @param labelsList
     */
    private static void changeOwnerIdAttrName(JSONObject data, List<SummaryDataPoJo> labelsList) {
        //客户公海池特殊处理 负责人->前负责人
        if (Objects.equals(data.getInteger(CustomerManagementEnum.IS_PUBLIC.getAttr()), 1)) {
            for(SummaryDataPoJo poJo : labelsList) {
                if (Objects.equals(poJo.getAttr(), CustomerManagementEnum.OWNER_ID.getAttr())) {
                    poJo.setAttrName(FieldTypeEnum.PRE_OWNER_ID.getDescription());
                    break;
                }
            }
        }
    }


}
